package pers.wchen.mybatis.generate.data.database;

import com.mysql.cj.api.mysqla.result.Resultset;
import pers.wchen.mybatis.generate.model.DatabaseTablePropertyVO;
import pers.wchen.mybatis.generate.util.CharsTransUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @作者： wchen
 * @描述： 数据库数据读取
 * @创建时间： 2018/2/9 14:10
 * @版本：Copyright 2018, Inc. All Rights Reserved.
 * @修改信息：
 */
public abstract class AbsDatabaseFactory implements BaseDatabase{

    private String url;
    private String driverName;
    private String username;
    private String password;
    private Connection conn = null;
    private PreparedStatement pst = null;

    public AbsDatabaseFactory(String url, String driverName, String username, String password) {
        this.url = url;
        this.driverName = driverName;
        this.username = username;
        this.password = password;
        try {
            Class.forName(driverName);//指定连接类型
            this.conn = DriverManager.getConnection(url, username, password);//获取连接
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * @描述: 数据库查询获取基本数据
     * @参数：
     * @返回值：
     * @创建人: wchen
     * @创建时间: 2018/2/9
     * @修改人和其它信息:
     */
    public List<DatabaseTablePropertyVO> getDatabaseData(String sql) {
        ResultSet resultset = null;
        List<DatabaseTablePropertyVO> tablePropertyVOS = null;
        try {
            resultset = doSqlQuery(sql);
            tablePropertyVOS = resultHandle(resultset);
        }catch (Exception e){

        }finally {
            close(resultset);
        }
        return tablePropertyVOS;
    }


    /**
     *  @描述: 获取表注释
     *  @参数： [sql]
     *  @返回值： java.util.Map
     *  @创建人: wchen
     *  @创建时间: 2018/2/9
     *  @修改人和其它信息:
     */
    public Map getOtherInfo(String sql) {
        ResultSet resultset = null;
        Map dataMap = null;
        try {
            resultset = doSqlQuery(sql);
            dataMap = getTableComponent(resultset);
        }catch (Exception e){

        }finally {
            close(resultset);
        }
        return dataMap;
    }

    /**
     *  @描述: 结果集处理转map
     *  @参数： [ret]
     *  @返回值： java.util.Map<java.lang.String,java.lang.String>
     *  @创建人: wchen
     *  @创建时间: 2018/2/9
     *  @修改人和其它信息:
     */
    private Map<String, String> getTableComponent(ResultSet ret) {
        Map<String, String> componentMap = new HashMap<String, String>();
        try {
            while (ret.next()) {
                System.out.println(ret.toString());
                String component = ret.getString(18);
                String tableName = ret.getString(1);
                componentMap.put(tableName, component);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
        return componentMap;
    }


    /**
     *  @描述: sql查询
     *  @参数： [sql]
     *  @返回值： java.sql.ResultSet
     *  @创建人: wchen
     *  @创建时间: 2018/2/9
     *  @修改人和其它信息:
     */
    private ResultSet doSqlQuery(String sql) throws Exception {
        pst = conn.prepareStatement(sql);//准备执行语句
        ResultSet ret = pst.executeQuery();//执行语句，得到结果集
        return ret;
    }


    /**
     *  @描述: 链接关闭
     *  @参数： [ret]
     *  @返回值： void
     *  @创建人: wchen
     *  @创建时间: 2018/2/9
     *  @修改人和其它信息:
     */
    private void close(ResultSet ret){
        try {
            if(ret!= null){
                ret.close();
            }
            if(pst != null){
                pst.close();//关闭连接
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    /**
     *  @描述: 结果集处理。特定vo
     *  @参数： [ret]
     *  @返回值： java.util.List<pers.wchen.mybatis.generate.model.DatabaseTablePropertyVO>
     *  @创建人: wchen
     *  @创建时间: 2018/2/9
     *  @修改人和其它信息:
     */
    private List<DatabaseTablePropertyVO> resultHandle(ResultSet ret) {
        List<DatabaseTablePropertyVO> list = new ArrayList<DatabaseTablePropertyVO>();
        try {
            while (ret.next()) {
                DatabaseTablePropertyVO tbVo = new DatabaseTablePropertyVO();
                String fieldName = transValue(ret.getString(1));
                //类型和长度
                String fieldType = transValue(ret.getString(2));
                int beginInt = fieldType.indexOf("(");
                String type = "";
                String length = "";
                if (beginInt == -1) {
                    type = fieldType;
                    length = "0";
                } else {
                    type = fieldType.substring(0, fieldType.indexOf("("));
                    length = fieldType.substring(fieldType.indexOf("(") + 1, fieldType.indexOf(")"));
                }
                String isNull = transValue(ret.getString(4));
                String isKey = ret.getString(5);
                String defaultValue = transValue(ret.getString(6));
                String extra = transValue(ret.getString(7));
                String comment = transValue(ret.getString(9));
                tbVo.setField(fieldName);
                tbVo.setType(type);
                tbVo.setLength(length);
                tbVo.setIsNull(isNull);
                tbVo.setIsKey(isKey);
                tbVo.setDefaultValue(defaultValue);
                tbVo.setExtra(extra);
                tbVo.setComment(comment);
                tbVo.setJdbcType(transJdbcType(type));
                tbVo.setJavaType(transJavaType(type));
                tbVo.setTransField(CharsTransUtil.transParam(fieldName));
                list.add(tbVo);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
        return list;
    }


    /**
     *  @描述: java数据类型转换
     *  @参数： [type]
     *  @返回值： java.lang.String
     *  @创建人: wchen
     *  @创建时间: 2018/2/9
     *  @修改人和其它信息:
     */
    abstract String transJavaType(String type);


    /**
     *  @描述:  jdbc类型转换
     *  @参数： [type]
     *  @返回值： java.lang.String
     *  @创建人: wchen
     *  @创建时间: 2018/2/9
     *  @修改人和其它信息:
     */
    abstract String transJdbcType(String type);


    /**
     *  @描述: 去空校验
     *  @参数： [value]
     *  @返回值： java.lang.String
     *  @创建人: wchen
     *  @创建时间: 2018/2/9
     *  @修改人和其它信息:
     */
    private String transValue(String value){
        if(value==null || value.equals("") || value.equals("null")){
            return "";
        }else{
            return value;
        }
    }

}
